/**
    This library contains the definitions of the channel descriptor data structures
    and common functionalities.
    For internal use.
*/
#ifndef SHM_COMMON_H
#define SHM_COMMON_H

#include "channel.h"
#include "synchr.h"
#include <pthread.h>

#define LINE_SIZE (16) // line size: 16 bytes to work with simd code

//#define LINE_SIZE (8) // line size: 8 bytes on ottavinareale

/*
    Channel descriptor structure
*/
struct channel_t
{
	union {
		struct {
			int type; // inheredited from base class (see shm.c)

			key_t key;
			int id;
			key_t altKey; // when set, receiver is receiving on this channel thru an Alternative

			lock_variable_t mutex;
			cond_variable_t cond_tosender; //condition variable used to signal an event towards the sender (by the receiver)
			cond_variable_t cond_toreceiver; //condition variable used to signal an event towards the receiver (by the sender)

			int size; // message size
			int fixedsize; // message size as a multiple of 8 bytes (due to cache line problems...)
/* TODO (dematteis#1#): Questo messages servira' da sincronizzazione per il partner....quindi va allocato opportunamente */
			int messages; // sent messages counter (number of messages actually present in the channel)
			int k; // asynchrony grade (o in case of synchronous channel)
			int j; // how many static vtgs are allocated in memory
			int nextVtg; // which is the next vtg to use
			int currVtg; // last vtg used

		};
		char null[1024];
	};
};

//mutex and cond initialization
void mutex_init( pthread_mutex_t *mutex );
void cond_init( pthread_cond_t *cond );

//synchronization on the channel
inline void __LClockChannel( struct channel_t *ch );
inline void __LCunlockChannel( struct channel_t *ch );

//alternative command
void __LCwakeUpAlternative( key_t altKey );
inline void __LCsetAltKey( struct channel_t *ch, key_t altKey );
inline int __LClockAlt( struct alternative_t *alt );
inline int __LCunlockAlt( struct alternative_t *alt );
inline int __LCwaitOnAlt( struct alternative_t *alt );
inline int __LCwakeUpAlt( struct alternative_t *alt );
 void printCH_as(struct channel_t *ch);

#endif
